package com.jwgf.smarowindingmachine_unity.ui;

import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import com.jwgf.common.ViewCache;
import com.jwgf.faultnavigation.FaultNavigationAttr;
import com.jwgf.faultnavigation.FaultNavigationMap;
import com.jwgf.fram.FramManager;
import com.jwgf.fram.FramManager.OnFramChangedListener;
import com.jwgf.group.GroupMap;
import com.jwgf.report.ShiftTimeRule;
import com.jwgf.smarowindingmachine_unity.R;
import com.jwgf.smarowindingmachine_unity.logic.MachineParameterSharedPreference;
import com.jwgf.smarowindingmachine_unity.logic.Report;
import com.jwgf.smarowindingmachine_unity.logic.SmaroWindingMachineCanReadSucceedListener;
import com.jwgf.smarowindingmachine_unity.logic.SmaroWindingMachineModBusReadParser;

import org.greenrobot.eventbus.EventBus;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.schedulers.Schedulers;

public class MachineStateRunningStateFragment extends BaseFragment implements OnFramChangedListener {
    public static final String fragmentTag = "MachineStateRunningStateFragment";
    private View v;
    private TextView txtCurrentShift;
    private TextView txtCurrentgroup;
    private TextView txtCurrentthroughput;
    private TextView txtCurrenteff;
    private TextView txtCurrentBucketWeight;
    private String totalBucketWeight;
    private String totalProductionEfficiency;
    private String totalBucketWeightWinding;
    private GifSurfaceView gifContainer;
    private ImageView pngContainer;
    private final static int ROW_OF_BUTTON = 4;
    private final static int COL_OF_BUTTON = 18;
    MachineParameterSharedPreference sp = MachineParameterSharedPreference.getInstance();
    private FramManager fm = FramManager.getInstance();
    DecimalFormat df = new DecimalFormat("0.00");

    private Disposable disposable;
    private int plcErrorArrayVCRO[][] = {
            {0, R.drawable.machine_fault_07_vcro}, // 空管输送带卡管505.1
            {0, R.drawable.machine_fault_06_vcro}, // 回丝箱门未关505.2
            {0, R.drawable.machine_fault_09_vcro}, // 水捻器水量不足505.4
            {0, R.drawable.machine_fault_03_vcro}, // 筒纱电机过热504.0
            {0, R.drawable.machine_fault_00_vcro}, // 游动吹吸风小车电机故障504.1
            {0, R.drawable.machine_fault_08_vcro}, // 空管输送带电机故障504.2
            {0, R.drawable.machine_fault_05_vcro}, // 压缩气压过低504.3
            {0, R.drawable.machine_fault_04_vcro}, // 负压风机变频故障504.4
            {0, R.drawable.machine_fault_02_vcro}, // 直流电源故障504.5
            {0, R.drawable.machine_fault_01_vcro}, // 急停504.6
    };
    private int plcErrorArrayVCROM[][] = {
            {0, R.drawable.machine_fault_07_vcrom}, // 空管输送带卡管505.1
            {0, R.drawable.machine_fault_06_vcrom}, // 回丝箱门未关505.2
            {0, R.drawable.machine_fault_09_vcrom}, // 水捻器水量不足505.4
            {0, R.drawable.machine_fault_03_vcrom}, // 筒纱电机过热504.0
            {0, R.drawable.machine_fault_00_vcrom}, // 游动吹吸风小车电机故障504.1
            {0, R.drawable.machine_fault_08_vcrom}, // 空管输送带电机故障504.2
            {0, R.drawable.machine_fault_05_vcrom}, // 压缩气压过低504.3
            {0, R.drawable.machine_fault_04_vcrom}, // 负压风机变频故障504.4
            {0, R.drawable.machine_fault_02_vcrom}, // 直流电源故障504.5
            {0, R.drawable.machine_fault_01_vcrom}, // 急停504.6
    };
    int[][] btn_mapping = {
            {R.id.btn_spindle_1, R.id.btn_spindle_2, R.id.btn_spindle_3, R.id.btn_spindle_4, R.id.btn_spindle_5,
                    R.id.btn_spindle_6, R.id.btn_spindle_7, R.id.btn_spindle_8, R.id.btn_spindle_9, R.id.btn_spindle_10,
                    R.id.btn_spindle_11, R.id.btn_spindle_12, R.id.btn_spindle_13, R.id.btn_spindle_14,
                    R.id.btn_spindle_15, R.id.btn_spindle_16, R.id.btn_spindle_17, R.id.btn_spindle_18},
            {R.id.btn_spindle_19, R.id.btn_spindle_20, R.id.btn_spindle_21, R.id.btn_spindle_22,
                    R.id.btn_spindle_23, R.id.btn_spindle_24, R.id.btn_spindle_25, R.id.btn_spindle_26,
                    R.id.btn_spindle_27, R.id.btn_spindle_28, R.id.btn_spindle_29, R.id.btn_spindle_30,
                    R.id.btn_spindle_31, R.id.btn_spindle_32, R.id.btn_spindle_33, R.id.btn_spindle_34,
                    R.id.btn_spindle_35, R.id.btn_spindle_36},
            {R.id.btn_spindle_37, R.id.btn_spindle_38, R.id.btn_spindle_39, R.id.btn_spindle_40,
                    R.id.btn_spindle_41, R.id.btn_spindle_42, R.id.btn_spindle_43, R.id.btn_spindle_44,
                    R.id.btn_spindle_45, R.id.btn_spindle_46, R.id.btn_spindle_47, R.id.btn_spindle_48,
                    R.id.btn_spindle_49, R.id.btn_spindle_50, R.id.btn_spindle_51, R.id.btn_spindle_52,
                    R.id.btn_spindle_53, R.id.btn_spindle_54},
            {R.id.btn_spindle_55, R.id.btn_spindle_56, R.id.btn_spindle_57, R.id.btn_spindle_58,
                    R.id.btn_spindle_59, R.id.btn_spindle_60, R.id.btn_spindle_61, R.id.btn_spindle_62,
                    R.id.btn_spindle_63, R.id.btn_spindle_64, R.id.btn_spindle_65, R.id.btn_spindle_66,
                    R.id.btn_spindle_67, R.id.btn_spindle_68, R.id.btn_spindle_69, R.id.btn_spindle_70,
                    R.id.btn_spindle_71, R.id.btn_spindle_72}};
    private Button[][] btn_array = new Button[4][18];

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        v = ViewCache.getInstance().getView(R.layout.fragment_machine_state_running_state);
        txtCurrentShift = (TextView) v.findViewById(R.id.txtCurrentShift);
        txtCurrentgroup = (TextView) v.findViewById(R.id.txtCurrentgroup);
        txtCurrentthroughput = (TextView) v.findViewById(R.id.txtCurrentthroughput);
        txtCurrenteff = (TextView) v.findViewById(R.id.txtCurrenteff);
        txtCurrentBucketWeight = v.findViewById(R.id.txtCurrentWeight);
        gifContainer = (GifSurfaceView) v.findViewById(R.id.gif_container);
        gifContainer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                ArrayList<Integer> faultList = SmaroWindingMachineModBusReadParser.getInstance().getCurrentFaultList();
                for (Integer code : faultList) {
                    FaultNavigationAttr attr = FaultNavigationMap.getInstance().get(code);
                    if (attr != null) {
                        EventBus.getDefault().post(attr);
                        break;
                    }
                }

            }
        });

        pngContainer = v.findViewById(R.id.png_container);
        pngContainer.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                ArrayList<Integer> faultList = SmaroWindingMachineModBusReadParser.getInstance().getCurrentFaultList();
                for (Integer code : faultList) {
                    FaultNavigationAttr attr = FaultNavigationMap.getInstance().get(code);
                    if (attr != null) {
                        EventBus.getDefault().post(attr);
                        break;
                    }
                }
            }
        });

        txtCurrentShift.setText(ShiftTimeRule.getInstance().getCurrentShiftNum());
        txtCurrentgroup.setText(String.valueOf(GroupMap.getInstance().getGroupCount()));

        setupButtonSpindle();
        refreshError();
        fm.registerOnFramChangedListener(this);
        refresh();

        return v;
    }

    @Override
    public void onResume() {
        super.onResume();
        refreshError();
        refresh();
    }

    @Override
    public void onPause() {
        super.onPause();
        gifContainer.setVisibility(View.INVISIBLE);
        disposable.dispose();
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        if (hidden) {
            gifContainer.setVisibility(View.INVISIBLE);
            disposable.dispose();
            fm.unregisterOnFramChangedListener(this);

        } else {
            refreshError();
            refresh();
            fm.registerOnFramChangedListener(this);
        }
    }

    @Override
    public void onFramChanged(FramManager framManager, String key) {
        if (key.equals("252")) {
            int mt = Integer.parseInt(sp.getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0"));
            int value = framManager.getInt(key, 0);
            switch (mt) {
                case 0:
                case 1:
                case 4:
                    for (int i = 0; i < 15; i++) {
                        if (i == 8 || i == 9 || i == 10 || i == 11 || i == 12 || i == 13 || i == 14) {
                            if (((value >> i) & 0x01) == 0x01) {
                                plcErrorArrayVCROM[i - 5][0] = 1;
                            } else {
                                plcErrorArrayVCROM[i - 5][0] = 0;
                            }
                        } else if (i == 1) {
                            if (((value >> i) & 0x01) == 0x01) {
                                plcErrorArrayVCROM[0][0] = 1;
                            } else {
                                plcErrorArrayVCROM[0][0] = 0;
                            }
                        } else if (i == 2) {
                            if (((value >> i) & 0x01) == 0x01) {
                                plcErrorArrayVCROM[1][0] = 1;
                            } else {
                                plcErrorArrayVCROM[1][0] = 0;
                            }
                        } else if (i == 4) {
                            if (((value >> i) & 0x01) == 0x01) {
                                plcErrorArrayVCROM[2][0] = 1;
                            } else {
                                plcErrorArrayVCROM[2][0] = 0;
                            }
                        }
                    }
                    break;
                case 2:
                case 3:
                case 5:
                    for (int i = 0; i < 15; i++) {
                        if (i == 8 || i == 9 || i == 10 || i == 11 || i == 12 || i == 13 || i == 14) {
                            if (((value >> i) & 0x01) == 0x01) {
                                plcErrorArrayVCRO[i - 5][0] = 1;
                            } else {
                                plcErrorArrayVCRO[i - 5][0] = 0;
                            }
                        } else if (i == 1) {
                            if (((value >> i) & 0x01) == 0x01) {
                                plcErrorArrayVCRO[0][0] = 1;
                            } else {
                                plcErrorArrayVCRO[0][0] = 0;
                            }
                        } else if (i == 2) {
                            if (((value >> i) & 0x01) == 0x01) {
                                plcErrorArrayVCRO[1][0] = 1;
                            } else {
                                plcErrorArrayVCRO[1][0] = 0;
                            }
                        } else if (i == 4) {
                            if (((value >> i) & 0x01) == 0x01) {
                                plcErrorArrayVCRO[2][0] = 1;
                            } else {
                                plcErrorArrayVCRO[2][0] = 0;
                            }
                        }
                    }
                    break;
            }

            refreshError();


        }
    }

    public void refresh() {

        if (disposable == null || disposable.isDisposed()) {
            disposable = Observable.interval(5, TimeUnit.SECONDS)
                    .doOnNext(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            totalBucketWeight = df.format(Report.getInstance().getTotalBucketWeight());
                            totalProductionEfficiency = df.format(Report.getInstance().getTotalProductionEfficiency());
                            totalBucketWeightWinding = df.format(Report.getInstance().getTotalBucketWeightWinding());
                        }
                    })
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            txtCurrentShift.setText(ShiftTimeRule.getInstance().getCurrentShiftNum());
                            txtCurrentgroup.setText(String.valueOf(GroupMap.getInstance().getGroupCount()));
                            txtCurrentthroughput.setText(totalBucketWeight);
                            txtCurrenteff.setText(totalProductionEfficiency);
                            txtCurrentBucketWeight.setText(totalBucketWeightWinding);
//                    txtCurrentthroughput.setText("16.72");
//                    txtCurrenteff.setText("86.76");
                            updateButton();
                        }
                    });
        }

    }

    public void refreshError() {
        int mt = Integer.parseInt(sp.getValue(MachineParameterSharedPreference.MACHINE_MACHINE_TYPE, "0"));

        switch (mt) {
            case 0:
            case 1:
            case 4: {
                gifContainer.setVisibility(View.INVISIBLE);
                pngContainer.setVisibility(View.VISIBLE);
                ArrayList<Integer> list = new ArrayList<Integer>();
                list.add(R.drawable.machine_bk_vcrom);
                for (int i = 0; i <= 9; i++) {
                    if (plcErrorArrayVCROM[i][0] != 0) {
                        list.add(plcErrorArrayVCROM[i][1]);
                    }
                }
                generateImage(list);
                break;
            }
            case 2:
            case 3:
            case 5: {
                gifContainer.setVisibility(View.VISIBLE);
                pngContainer.setVisibility(View.INVISIBLE);
                ArrayList<Integer> list = new ArrayList<Integer>();
                list.add(R.drawable.machine_bk_vcro);
                for (int i = 0; i <= 9; i++) {
                    if (plcErrorArrayVCRO[i][0] != 0) {
                        list.add(plcErrorArrayVCRO[i][1]);
                    }
                }
                gifContainer.setMovieList(list);
                break;
            }
        }

    }

    private void generateImage(List<Integer> imageList) {
        Resources resources = getResources();
        Drawable[] layers = new Drawable[imageList.size()];
        for (int i = 0; i < imageList.size(); ++i) {
            layers[i] = resources.getDrawable(imageList.get(i));
        }
        LayerDrawable layerDrawable = new LayerDrawable(layers);
        pngContainer.setImageDrawable(layerDrawable);
    }

    /**
     * Setup color of spindle button and setup button click listener
     */
    private void setupButtonSpindle() {
        int spindleNumber = Integer.parseInt(sp.getValue(0x29, 0x01));
        for (int row_num = 0; row_num < ROW_OF_BUTTON; row_num++) {
            for (int col_num = 0; col_num < COL_OF_BUTTON; col_num++) {
                btn_array[row_num][col_num] = (Button) v.findViewById(btn_mapping[row_num][col_num]);
                int btnNumber = (col_num + 1) + (COL_OF_BUTTON * row_num);
                btn_array[row_num][col_num].setText(String.format("%d", btnNumber));
                btn_array[row_num][col_num].setTag(btnNumber);

                btn_array[row_num][col_num].setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Button b = (Button) v;
                        String value = b.getText().toString();
                        sp.setValue(MachineParameterSharedPreference.CURRENT_SPINDLE_NUMBER, value);
                        SwitchPageManager.getInstance().switchSecondMenu(getFragmentManager(), R.id.spindle_status_button);
                    }
                });
                if (btnNumber > spindleNumber)
                    btn_array[row_num][col_num].setVisibility(View.INVISIBLE);
                else
                    btn_array[row_num][col_num].setVisibility(View.VISIBLE);
            }
        }

    }

    private void updateButton() {
        for (int row_num = 0; row_num < ROW_OF_BUTTON; row_num++) {
            for (int col_num = 0; col_num < COL_OF_BUTTON; col_num++) {
                int btnNumber = (col_num + 1) + (COL_OF_BUTTON * row_num);

                //单锭通讯状态
                if (!SmaroWindingMachineCanReadSucceedListener.getInstance().getSpindleToken(btnNumber)) {
                    btn_array[row_num][col_num]
                            .setTextColor(getResources().getColor(R.color.pm_rectangle_yellow));
                } else {
                    btn_array[row_num][col_num]
                            .setTextColor(getResources().getColor(R.color.white));
                }
                //单锭启停状态
                String key62 = btnNumber + "-" + (0x62 & 0xff) + "-" + 1;
                int data62DC_bit11 = fm.getInt(key62, 0) & 0x800;

                //单锭开始运行时此信号为”1”,当单锭因按下停止按钮或故障停车时此信号输出为”0”
                if (data62DC_bit11 != 0) {
                    btn_array[row_num][col_num]
                            .setBackgroundDrawable(getResources().getDrawable(R.drawable.btn_spindle_red_selector));
                } else {
                    btn_array[row_num][col_num]
                            .setBackgroundDrawable(getResources().getDrawable(R.drawable.btn_spindle_green_selector));
                }
            }
        }
    }
}
